package com.hoshiicloud.saleorder.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hoshiicloud.common.exception.ServiceException;
import com.hoshiicloud.common.query.OmnipotentWrapper;
import com.hoshiicloud.common.rpc.Response;
import com.hoshiicloud.common.utils.BeanUtils;
import com.hoshiicloud.saleorder.entity.OrderInfo;
import com.hoshiicloud.saleorder.param.OrderInfoAddParam;
import com.hoshiicloud.saleorder.param.OrderInfoQueryParam;
import com.hoshiicloud.saleorder.param.OrderInfoUpdateParam;
import com.hoshiicloud.saleorder.service.OrderInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 订单信息 控制器
 * </p>
 *
 * @author zhangshuhu
 * @since 2019-06-03
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/saleorder/order-info")
@Api(value = "销售订单", tags = {"订单信息管理"})
public class OrderInfoController {

    @Autowired
    private OrderInfoService orderInfoService;

    /**
     * @param param
     * @return com.hoshiibuy.common.rpc.Response
     * @description: 分页查询订单信息
     */
    @ApiOperation(value = "分页查询订单信息")
    @PostMapping("/query/page")
    public Response page(@RequestBody @Valid OrderInfoQueryParam param) {
        try {
            log.info("分页查询订单信息");
            QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(param.getCompanyId() != null, OrderInfo::getCompanyId, param.getCompanyId())
                    .eq(param.getPlatformId() != null, OrderInfo::getPlatformId, param.getPlatformId())
                    .eq(param.getStoreId() != null, OrderInfo::getStoreId, param.getStoreId())
                    .in(param.getMainId() != null, OrderInfo::getMainId, param.getMainId())
                    .eq(StringUtils.isNotBlank(param.getMainNo()), OrderInfo::getMainNo, param.getMainNo())
                    .eq(StringUtils.isNotBlank(param.getOrderNo()), OrderInfo::getOrderNo, param.getOrderNo())
                    .eq(param.getMemberId() != null, OrderInfo::getMemberId, param.getMemberId())
                    .eq(StringUtils.isNotBlank(param.getInvoiceNo()), OrderInfo::getInvoiceNo, param.getInvoiceNo())
                    .eq(StringUtils.isNotBlank(param.getToBuyer()), OrderInfo::getToBuyer, param.getToBuyer())
                    .eq(StringUtils.isNotBlank(param.getPayNote()), OrderInfo::getPayNote, param.getPayNote())
                    .eq(param.getGoodsAmount() != null, OrderInfo::getGoodsAmount, param.getGoodsAmount())
                    .eq(param.getShippingFee() != null, OrderInfo::getShippingFee, param.getShippingFee())
                    .eq(param.getInsureFee() != null, OrderInfo::getInsureFee, param.getInsureFee())
                    .eq(param.getPayFee() != null, OrderInfo::getPayFee, param.getPayFee())
                    .eq(param.getPackFee() != null, OrderInfo::getPackFee, param.getPackFee())
                    .eq(param.getTax() != null, OrderInfo::getTax, param.getTax())
                    .eq(param.getOrderAmount() != null, OrderInfo::getOrderAmount, param.getOrderAmount())
                    .eq(param.getAmount() != null, OrderInfo::getAmount, param.getAmount())
                    .eq(param.getBackAmount() != null, OrderInfo::getBackAmount, param.getBackAmount())
                    .eq(param.getCoinsAmount() != null, OrderInfo::getCoinsAmount, param.getCoinsAmount())
                    .eq(param.getPaidTime() != null, OrderInfo::getPaidTime, param.getPaidTime())
                    .eq(param.getCancelledTime() != null, OrderInfo::getCancelledTime, param.getCancelledTime())
                    .eq(param.getDeliveryTime() != null, OrderInfo::getDeliveryTime, param.getDeliveryTime())
                    .eq(param.getReceivedTime() != null, OrderInfo::getReceivedTime, param.getReceivedTime())
                    .eq(param.getBenefitsAmount() != null, OrderInfo::getBenefitsAmount, param.getBenefitsAmount())
                    .eq(param.getBalanceAmount() != null, OrderInfo::getBalanceAmount, param.getBalanceAmount())
                    .eq(param.getPoints() != null, OrderInfo::getPoints, param.getPoints())
                    .eq(param.getDeleted() != null, OrderInfo::getDeleted, param.getDeleted())
                    .eq(StringUtils.isNotBlank(param.getSpuName()), OrderInfo::getSpuName, param.getSpuName())
                    .eq(StringUtils.isNotBlank(param.getSkuName()), OrderInfo::getSkuName, param.getSkuName())
                    .eq(StringUtils.isNotBlank(param.getSpuNo()), OrderInfo::getSpuNo, param.getSpuNo())
                    .eq(param.getSpuId() != null, OrderInfo::getSpuId, param.getSpuId())
                    .eq(StringUtils.isNotBlank(param.getSkuNo()), OrderInfo::getSkuNo, param.getSkuNo())
                    .eq(param.getSkuId() != null, OrderInfo::getSkuId, param.getSkuId())
                    .eq(param.getRate() != null, OrderInfo::getRate, param.getRate())
                    .eq(param.getRateAmount() != null, OrderInfo::getRateAmount, param.getRateAmount())
                    .eq(StringUtils.isNotBlank(param.getSpuExtendProp()), OrderInfo::getSpuExtendProp, param.getSpuExtendProp())
                    .eq(StringUtils.isNotBlank(param.getSpuExtendSpec()), OrderInfo::getSpuExtendSpec, param.getSpuExtendSpec())
                    .eq(StringUtils.isNotBlank(param.getSkuExtendProp()), OrderInfo::getSkuExtendProp, param.getSkuExtendProp())
                    .eq(param.getSaleUnitPrice() != null, OrderInfo::getSaleUnitPrice, param.getSaleUnitPrice())
                    .eq(param.getUnitPrice() != null, OrderInfo::getUnitPrice, param.getUnitPrice())
                    .eq(param.getQuantity() != null, OrderInfo::getQuantity, param.getQuantity())
                    .eq(param.getActivityNo() != null, OrderInfo::getActivityNo, param.getActivityNo())
                    .eq(param.getOwn() != null, OrderInfo::getOwn, param.getOwn())
                    .eq(param.getOverseas() != null, OrderInfo::getOverseas, param.getOverseas())
                    .eq(param.getOrderStatus() != null, OrderInfo::getOrderStatus, param.getOrderStatus())
                    .eq(param.getShippingStatus() != null, OrderInfo::getShippingStatus, param.getShippingStatus())
                    .eq(param.getPayStatus() != null, OrderInfo::getPayStatus, param.getPayStatus())
                    .eq(param.getServiceStatus() != null, OrderInfo::getServiceStatus, param.getServiceStatus())
                    .eq(StringUtils.isNotBlank(param.getServiceRefNo()), OrderInfo::getServiceRefNo, param.getServiceRefNo());
            IPage<OrderInfo> page = new Page<>(Long.parseLong(param.getPageNumber()), Long.parseLong(param.getPageSize()));
            String key = "OrderInfoQueryParam{" + param.toString() + "} ,Page{pageNumber=" + param.getPageNumber() + ",pageSize=" + param.getPageSize() + "}";
            // queryWrapper.select(BeanUtils.getSqlSelect(OrderInfo.class));
            return Response.data(orderInfoService.page(page, queryWrapper, key));
        } catch (Exception e) {
            log.error("分页查询订单信息异常", e);
            throw new ServiceException("分页查询订单信息异常");
        }


    }

    /**
     * 查询子订单信息
     *
     * @param param 查询参数
     * @return Response<OrderInfo>
     */
    @ApiOperation(value = "查询子订单信息", notes = "查询所有子订单信息")
    @PostMapping("/list")
    public Response<List<OrderInfo>> list(@RequestBody @Valid OrderInfoQueryParam param) {
        try {
            log.info("查询子订单信息");
            QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(param.getCompanyId() != null, OrderInfo::getCompanyId, param.getCompanyId())
                    .eq(param.getPlatformId() != null, OrderInfo::getPlatformId, param.getPlatformId())
                    .eq(param.getStoreId() != null, OrderInfo::getStoreId, param.getStoreId())
                    .in(param.getMainId() != null, OrderInfo::getMainId, param.getMainId())
                    .eq(StringUtils.isNotBlank(param.getMainNo()), OrderInfo::getMainNo, param.getMainNo())
                    .eq(StringUtils.isNotBlank(param.getOrderNo()), OrderInfo::getOrderNo, param.getOrderNo())
                    .eq(param.getMemberId() != null, OrderInfo::getMemberId, param.getMemberId())
                    .eq(StringUtils.isNotBlank(param.getInvoiceNo()), OrderInfo::getInvoiceNo, param.getInvoiceNo())
                    .eq(StringUtils.isNotBlank(param.getToBuyer()), OrderInfo::getToBuyer, param.getToBuyer())
                    .eq(StringUtils.isNotBlank(param.getPayNote()), OrderInfo::getPayNote, param.getPayNote())
                    .eq(param.getGoodsAmount() != null, OrderInfo::getGoodsAmount, param.getGoodsAmount())
                    .eq(param.getShippingFee() != null, OrderInfo::getShippingFee, param.getShippingFee())
                    .eq(param.getInsureFee() != null, OrderInfo::getInsureFee, param.getInsureFee())
                    .eq(param.getPayFee() != null, OrderInfo::getPayFee, param.getPayFee())
                    .eq(param.getPackFee() != null, OrderInfo::getPackFee, param.getPackFee())
                    .eq(param.getTax() != null, OrderInfo::getTax, param.getTax())
                    .eq(param.getOrderAmount() != null, OrderInfo::getOrderAmount, param.getOrderAmount())
                    .eq(param.getAmount() != null, OrderInfo::getAmount, param.getAmount())
                    .eq(param.getBackAmount() != null, OrderInfo::getBackAmount, param.getBackAmount())
                    .eq(param.getCoinsAmount() != null, OrderInfo::getCoinsAmount, param.getCoinsAmount())
                    .eq(param.getPaidTime() != null, OrderInfo::getPaidTime, param.getPaidTime())
                    .eq(param.getCancelledTime() != null, OrderInfo::getCancelledTime, param.getCancelledTime())
                    .eq(param.getDeliveryTime() != null, OrderInfo::getDeliveryTime, param.getDeliveryTime())
                    .eq(param.getReceivedTime() != null, OrderInfo::getReceivedTime, param.getReceivedTime())
                    .eq(param.getBenefitsAmount() != null, OrderInfo::getBenefitsAmount, param.getBenefitsAmount())
                    .eq(param.getBalanceAmount() != null, OrderInfo::getBalanceAmount, param.getBalanceAmount())
                    .eq(param.getPoints() != null, OrderInfo::getPoints, param.getPoints())
                    .eq(param.getDeleted() != null, OrderInfo::getDeleted, param.getDeleted())
                    .eq(StringUtils.isNotBlank(param.getSpuName()), OrderInfo::getSpuName, param.getSpuName())
                    .eq(StringUtils.isNotBlank(param.getSkuName()), OrderInfo::getSkuName, param.getSkuName())
                    .eq(StringUtils.isNotBlank(param.getSpuNo()), OrderInfo::getSpuNo, param.getSpuNo())
                    .eq(param.getSpuId() != null, OrderInfo::getSpuId, param.getSpuId())
                    .eq(StringUtils.isNotBlank(param.getSkuNo()), OrderInfo::getSkuNo, param.getSkuNo())
                    .eq(param.getSkuId() != null, OrderInfo::getSkuId, param.getSkuId())
                    .eq(param.getRate() != null, OrderInfo::getRate, param.getRate())
                    .eq(param.getRateAmount() != null, OrderInfo::getRateAmount, param.getRateAmount())
                    .eq(StringUtils.isNotBlank(param.getSpuExtendProp()), OrderInfo::getSpuExtendProp, param.getSpuExtendProp())
                    .eq(StringUtils.isNotBlank(param.getSpuExtendSpec()), OrderInfo::getSpuExtendSpec, param.getSpuExtendSpec())
                    .eq(StringUtils.isNotBlank(param.getSkuExtendProp()), OrderInfo::getSkuExtendProp, param.getSkuExtendProp())
                    .eq(param.getSaleUnitPrice() != null, OrderInfo::getSaleUnitPrice, param.getSaleUnitPrice())
                    .eq(param.getUnitPrice() != null, OrderInfo::getUnitPrice, param.getUnitPrice())
                    .eq(param.getQuantity() != null, OrderInfo::getQuantity, param.getQuantity())
                    .eq(param.getActivityNo() != null, OrderInfo::getActivityNo, param.getActivityNo())
                    .eq(param.getOwn() != null, OrderInfo::getOwn, param.getOwn())
                    .eq(param.getOverseas() != null, OrderInfo::getOverseas, param.getOverseas())
                    // 这里设置的是大于等于当前订单状态的
                    .ge(param.getOrderStatus() != null, OrderInfo::getOrderStatus, param.getOrderStatus())
                    .eq(param.getShippingStatus() != null, OrderInfo::getShippingStatus, param.getShippingStatus())
                    .eq(param.getPayStatus() != null, OrderInfo::getPayStatus, param.getPayStatus())
                    .eq(param.getServiceStatus() != null, OrderInfo::getServiceStatus, param.getServiceStatus())
                    .eq(StringUtils.isNotBlank(param.getServiceRefNo()), OrderInfo::getServiceRefNo, param.getServiceRefNo());
            return Response.data(orderInfoService.list(queryWrapper));
        } catch (Exception e) {
            log.error("查询子订单信息异常", e);
            throw new ServiceException("查询子订单信息异常");
        }
    }

    /**
     * @param id
     * @return com.hoshiibuy.common.rpc.Response
     * @description: 根据id查询订单信息
     */
    @GetMapping("/{id}")
    @ApiOperation(value = "根据id查询订单信息")
    @ApiParam(name = "id", value = "主键ID", required = true)
    public Response<OrderInfo> queryById(@PathVariable("id") Long id) {
        return Response.data(orderInfoService.getById(id));
    }

    /**
     * @param param
     * @return com.hoshiibuy.common.rpc.Response
     * @description: 新增
     */
    @PostMapping("/save")
    @ApiOperation(value = "新增订单信息")
    public Response<Boolean> save(@RequestBody @Valid OrderInfoAddParam param) {
        OrderInfo entity;
        try {
            entity = BeanUtils.covertType(param, OrderInfo.class);
        } catch (Exception e) {
            log.error("新增订单信息转换类型异常 {}", e.getMessage());
            throw new ServiceException("新增订单信息异常");
        }
        return Response.data(orderInfoService.save(entity));

    }

    /**
     * @param param
     * @return com.hoshiibuy.common.rpc.Response
     * @description: 修改订单信息
     */
    @PutMapping("/update")
    @ApiOperation(value = "修改订单信息")
    public Response<Boolean> update(@RequestBody @Valid OrderInfoUpdateParam param) {
        OrderInfo entity;
        try {
            entity = BeanUtils.covertType(param, OrderInfo.class);

        } catch (Exception e) {
            log.error("修改订单信息类型转换异常", e);
            throw new ServiceException("修改订单信息异常");
        }
        return Response.data(orderInfoService.updateById(entity));
    }

    /**
     * @param id
     * @return com.hoshiibuy.common.rpc.Response
     * @description: 删除订单信息
     */
    @DeleteMapping("/delete/{id}")
    @ApiOperation(value = "删除订单信息")
    @ApiParam(name = "id", value = "主键ID", required = true)
    public Response<Boolean> delete(@PathVariable("id") Long id) {
        return Response.data(orderInfoService.deleteById(id));
    }

    /**
     * @Author:campchen
     * @Description: StringUtils.join(ids, " ") 为缓存中添加唯一KEY  如不合适可选择更好方法
     * @Date:上午 10:18 2019/5/11
     * @Param: ids
     * @return: com.hoshiibuy.common.rpc.Response
     */
    @ApiOperation(value = "根据id集合查询订单信息")
    @GetMapping("/getByIds")
    public Response<List<OrderInfo>> getByIds(@RequestParam("ids") List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Response.failed("子订单ID集合不能为空");
        }
        ids.sort(null);
        return Response.data(orderInfoService.getByIds(ids, StringUtils.join(ids, "")));
    }

    /**
     * 根据扩展spu主键组查询销售数量
     *
     * @param spuIds 扩展spu主键组
     * @return List<Map < String, Object>>
     */
    @GetMapping("/selectSalesCountBySpuIds")
    @ApiOperation(value = "根据ID组查询", notes = "根据扩展spu主键组查询销售数量", consumes = MediaType.ALL_VALUE)
    public Response<List<Map<String, Object>>> selectSalesCountBySpuIds(@RequestParam("spuIds") List<Long> spuIds, @RequestParam("status") Integer status) {
        Response<List<Map<String, Object>>> rs;
        try {
            QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("spu_id", spuIds);
            queryWrapper.ge("order_status", status);
            rs = Response.data(orderInfoService.selectSalesCountBySpuIds(queryWrapper));
        } catch (Exception e) {
            log.error("根据扩展spu主键组查询销售数量异常：", e.getMessage());
            rs = Response.failed("根据扩展spu主键组查询销售数量异常: " + e.getMessage());
        }
        return rs;
    }

    /**
     * 根据总店分组查询已售数量
     *
     * @param status 订单状态
     * @return List<Map < String, Object>>
     */
    @GetMapping("/selectSalesCountGroupByStorePid")
    @ApiOperation(value = "根据ID组查询", notes = "根据总店分组查询已售数量", consumes = MediaType.ALL_VALUE)
    public Response<List<Map<String, Object>>> selectSalesCountGroupByStorePid(@RequestParam("status") Integer status) {
        Response<List<Map<String, Object>>> rs;
        try {
            QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.ge("o.order_status", status);
            rs = Response.data(orderInfoService.selectSalesCountGroupByStorePid(queryWrapper));
        } catch (Exception e) {
            log.error("根据总店分组查询已售数量异常：", e.getMessage());
            rs = Response.failed("根据总店分组查询已售数量异常: " + e.getMessage());
        }
        return rs;
    }

    /**
     * 按店铺分组获取店铺粉丝数和购买指数
     *
     * @param status 订单状态
     * @return Response<List < Map < String, Object>>>
     */
    @ApiOperation(value = "按店铺分组获取店铺粉丝数和购买指数")
    @GetMapping("/getStoreFansAndBuyExponentGroupById")
    public Response<List<Map<String, Object>>> getStoreFansAndBuyExponentGroupById(@RequestParam("status") Integer status) {
        Response<List<Map<String, Object>>> rs;
        try {
            QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.ge("o.order_status", status);
            rs = Response.data(orderInfoService.getStoreFansAndBuyExponentGroupById(queryWrapper));
        } catch (Exception e) {
            log.error("按店铺分组获取店铺粉丝数和购买指数异常：", e.getMessage());
            rs = Response.failed("按店铺分组获取店铺粉丝数和购买指数异常: " + e.getMessage());
        }
        return rs;
    }


    @ApiOperation(value = "根据主订单ID 获取子订单列表")
    @GetMapping("/listByMainId/{mainId}")
    public Response<List<OrderInfo>> listByMainId(@PathVariable("mainId") Long mainId) {
        return Response.data(orderInfoService.listByMainId(mainId));
    }

    @ApiOperation(value = "根据自定义条件查询商品子单信息")
    @PostMapping("/omniQueryOrderInfo")
    public Response omniQueryOrderInfo(@RequestBody List<OmnipotentWrapper> wrappers) {
        String key = wrappers.toString();
        List<OrderInfo> orderMains = orderInfoService.omniQueryOrderMain(wrappers, key);
        return Response.data(orderMains);
    }
}
